/**
 * 案例，模拟 把 elementUI 的 form 表单校验 通过 Promise.resolve() 转换为 标准的 promise 形式
 * @param callBack
 */
function validate_form(callBack){
    for (let i = 0; i < 5; i++) {
        console.log("正在执行表单校验第",i,"项")
        callBack(false,()=>{
            console.log("啥也不是")
        })
    }
    console.log("表单校验完成，最后执行回调用户代码")
    callBack(true,()=>{
        console.log("已关闭loading")
    })
}

console.log("常规的表单校验")

validate_form((validate,done)=>{
    if(validate){
        console.log("正在执行ajax请求")
        setTimeout(()=>{
            console.log("ajax响应成功")
            done()
        },500)

    }
})

/**
 * 把 elementUI 的 form 校验封装为一个 resolvable
 * @param resolve
 * @param reject
 */
function formValidateResolveRejectWrapper(resolve,reject){
    validate_form((validate,done)=>{
        if(validate){
            resolve(done)
        }
    })

    /*
    也可以把 Promise.race() 竞态条件移动到这里来
    setTimeout(()=>{
        reject()
    },1000)*/
}

/**
 * 把自定义的 resolvable 转换为 thenable 的 规范化的 promise 对象
 * Promise.resolve(..)也会展开 thenable 值（前面已多次介绍）。
 * 在这种情况下，返回的 Promise 采用传入的这个 thenable 的最终决议值，可能是完成，也可能是拒绝
 * 如果传入的是真正的 Promise，Promise.resolve(..)
 * 什么都不会做，只会直接把这个值返回。所以，对你不了解属性的值调用 Promise.resolve(..)，
 * 如果它恰好是一个真正的 Promise，是不会有额外的开销的。
 * @type {Promise<{then: formValidateResolveRejectWrapper}>}
 */
const p = Promise.resolve({
    then:formValidateResolveRejectWrapper
})

const timeoutRejectPromise = new Promise((resolve, reject)=>{
    reject("超时先成功")
})

/**
 * 新增一个竞态条件，任意一个完成就执行 then() 步骤
 * 避免表单一直校验，没有成功，超时了就执行失败步骤
 */
Promise.race([p,timeoutRejectPromise]).then(done=>{
    console.log("promise 中执行ajax请求")
    setTimeout(()=>{
        console.log("promise 中的ajax 响应完成")
        done()
    },500)
},err=>{
    console.log("超时，表单校验失败",err)
})
